﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Xml.Linq;
using SiteChecker.Models;
using SiteChecker.Interfaces;
using GalaSoft.MvvmLight.Command;

namespace SiteChecker.ViewModels
{
    public class SiteListViewModel : INotifyPropertyChanged
    {
        #region Constructors
        public SiteListViewModel()
        {
            Sites = new ObservableCollection<Site>();

            RefreshAllCommand = new RelayCommand(RefreshAll);
            AddNewCommand = new RelayCommand(AddNewItem);
            LoadProfileCommand = new RelayCommand(LoadProfile);
            SaveProfileCommand = new RelayCommand(SaveProfile);
            AddNewCommandTextBox = new RelayCommand<KeyEventArgs>(AddNewItem);
        }
        #endregion

        #region Properties
        public List<string> SitesKeys
        {
            get
            {
                List<string> keys = new List<string>();
                foreach(ISiteStatus site in Sites)
                {
                    keys.Add(site.URL);
                }
                return keys;
            }
        }
        private ObservableCollection<Site> _sites;
        public ObservableCollection<Site> Sites
        {
            get
            {
                return _sites;
            }
            set
            {
                if (_sites != value)
                {
                    _sites = value;
                    OnPropertyChanged("Sites");
                }                
            }
        }
        private string _NewSiteUrl;
        public string NewSiteUrl 
        {
            get
            {
                return _NewSiteUrl;
            }
            set
            {
                _NewSiteUrl = value;
                OnPropertyChanged("NewSiteUrl");
            }

        }
        #endregion

        #region INotifyPropertyChanged Members
        private void OnPropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
        public event PropertyChangedEventHandler PropertyChanged;

        #endregion

        #region Command Methods
        public ICommand RefreshAllCommand
        {
            get;
            private set;
        }
        private void RefreshAll()
        {
            foreach (Site site in Sites)
            {
                site.Refresh();
            }
        }
        
        public ICommand AddNewCommand
        {
            get;
            private set;
        }
        public RelayCommand<KeyEventArgs> AddNewCommandTextBox
        {
            get;
            private set;
        }
        private void AddNewItem(KeyEventArgs e)
        {
            if (e.Key == Key.Enter)
                AddNewItem();
        }
        private void AddNewItem()
        {
            if (!String.IsNullOrWhiteSpace(NewSiteUrl) && !SitesKeys.Contains(NewSiteUrl))
            {
                Site site = new Site(NewSiteUrl);
                Sites.Add(site);
                NewSiteUrl = String.Empty;
            }
        }
        
        public ICommand LoadProfileCommand
        {
            get;
            private set;
        }
        private void LoadProfile()
        {
            if (MessageBox.Show("Are you sure you want to load a new profile?" + Environment.NewLine + "Any existing profile data will be lost unless you have saved the current profile.", 
                "Confirm replacement of current profile", 
                MessageBoxButton.OKCancel) == MessageBoxResult.OK)
            {
                OpenFileDialog openFileDialog = new OpenFileDialog()
                {
                    Multiselect = false,
                    Filter = "XML files (*.xml)|*.xml",
                    FilterIndex = 1
                };

                if (openFileDialog.ShowDialog() == true)
                {
                    using (StreamReader reader = openFileDialog.File.OpenText())
                    {
                        // Store file content in 'text' variable
                        string documentText = reader.ReadToEnd();
                        XDocument sitesXmlDocument = XDocument.Parse(documentText);
                        var sites = from site in sitesXmlDocument.Descendants("site")
                                    select new Site((string)site.Element("url"));
                        Sites = new ObservableCollection<Site>(sites);
                    }
                }
            }
        }
        public ICommand SaveProfileCommand
        {
            get;
            private set;
        }
        private void SaveProfile()
        {
            XDocument sitesXml = new XDocument(new XElement("sites"));
            foreach (ISiteStatus site in Sites)
                sitesXml.Element("sites").Add(new XElement("site", new XElement("url", site.URL)));

            SaveFileDialog sfd = new SaveFileDialog()
            {
                DefaultExt = "xml",
                Filter = "XML files (*.xml)|*.xml",
                FilterIndex = 1
            };
            if (sfd.ShowDialog() == true)
            {
                // User selected item. Only property we can get to is.
                using (Stream stream = sfd.OpenFile())
                {
                    sitesXml.Save(stream);
                    stream.Close();
                }
            }
        }
        #endregion
    }
}
